/*
    Zwraca wartosc funkcji zredukowanej do jednoargumentowej w kierunku d i przesunieciu alfa
*/
double directedF(OptimFunc of, int n, double*x, double*d, double alfa){
    double sx[n];
    int i;
//
    for (i=0; i<n; ++i) sx[i] = x[i] + alfa*d[i];
    return of(sx, n);
}

/*
    Zwraca wartosc pochodnej z funkcji zredukowanej do kierunkowej
*/

double directedG(OptimFunc of, int n, double*x, double*d, double alfa){
    return (directedF(of,n,x,d,alfa+EPS) - directedF(of,n,x,d,alfa)) / EPS;
}

int gradient(OptimFunc of, int n, double*x, /*out*/ double*g){
    int i,j;
    double d[n];
    for (i=0; i<n; ++i){
        for (j=0; j<n; ++j){
            d[j] = 0;
        }
        d[i] = 1;
        g[i] = directedG(of, n, x, d, 0);
    }
    return 0;
};
